package xyz.ibenben.zhongdian.common.redis;

import org.apache.ibatis.cache.Cache;
import org.springframework.data.redis.connection.*;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import xyz.ibenben.zhongdian.common.exception.*;

import java.util.Set;
import java.util.concurrent.locks.*;

/**
 * 使用Redis来做Mybatis的二级缓存
 * 实现Mybatis的Cache接口
 * @author chenjian
 * @since 2017年10月18日下午5:17:22
 */
public class MybatisRedisCache implements Cache {
	private static final String PREFIX = "SYS_CONFIG:";

	private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(true);

	private String id;
	private JdkSerializationRedisSerializer jdkSerializer = new JdkSerializationRedisSerializer();

	private static RedisConnectionFactory redisConnectionFactory;

	/**
	 * 构造函数
	 * @param id
	 */
	public MybatisRedisCache(final String id) {
		if (id == null) {
			throw new MyException(ExceptionEnum.NEEDIDEXCEPTION, new Exception());
		}
		this.id = id;
	}

	/**
	 * 获取主键
	 * @return
	 */
	@Override
	public String getId() {
		return this.id;
	}

	/**
	 * 设置对象
	 * @param key 参数
	 * @param value 参数
	 */
	@Override
	public void putObject(Object key, Object value) {
		RedisClusterConnection conn = redisConnectionFactory
				.getClusterConnection();
		if (key == null)
			return;
		String strKey = PREFIX + key.toString();
		conn.set(strKey.getBytes(), jdkSerializer.serialize(value));
		conn.close();
	}

	/**
	 * 获取对象
	 * @param key 参数
	 * @return 返回值
	 */
	@Override
	public Object getObject(Object key) {
		if (key != null) {
			String strKey = PREFIX + key.toString();
			RedisClusterConnection conn = redisConnectionFactory
					.getClusterConnection();
			byte[] bs = conn.get(strKey.getBytes());
			conn.close();
			return jdkSerializer.deserialize(bs);
		}
		return null;
	}

	/**
	 * 删除对象
	 * @param key 参数
	 * @return 返回值
	 */
	@Override
	public Object removeObject(Object key) {
		if (key != null) {
			RedisClusterConnection conn = redisConnectionFactory
					.getClusterConnection();
			conn.del(key.toString().getBytes());
			conn.close();
		}
		return null;
	}

	/**
	 * 清空数据
	 */
	@Override
	public void clear() {
		// 关键代码，data更新时清理缓存
		RedisClusterConnection conn = redisConnectionFactory
				.getClusterConnection();
		Set<byte[]> keys = conn.keys((PREFIX+"*").getBytes());
		for (byte[] bs : keys) {
			conn.del(bs);
		}
		conn.close();
	}

	/**
	 * 获取大小
	 * @return 返回值
	 */
	@Override
	public int getSize() {
		return 0;
	}

	/**
	 * 获取读写锁
	 * @return
	 */
	@Override
	public ReadWriteLock getReadWriteLock() {
		return this.readWriteLock;
	}

	/**
	 * 获取redis工厂对象
	 * @param redisConnectionFactory 参数
	 */
	public static void setRedisConnectionFactory(RedisConnectionFactory redisConnectionFactory) {
		MybatisRedisCache.redisConnectionFactory = redisConnectionFactory;
	}
}
